﻿// Decompiled with JetBrains decompiler
// Type: Microsoft.InfoCards.SecondaryIndexList
// Assembly: infocard, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
// MVID: 8E14765A-6610-409A-BA36-099A0642905D
// Assembly location: E:\git\ALLIDA\windll\infocard.exe

using Microsoft.InfoCards.Diagnostics;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Globalization;

namespace Microsoft.InfoCards
{
  internal class SecondaryIndexList
  {
    private Hashtable m_indexes;
    private bool m_isOpen;
    private IComparer<IntPtr> m_searchComparer;
    private IComparer<IntPtr> m_sortComparer;

    public SecondaryIndexList(SecondaryIndexDefinition[] definitions)
    {
      if (definitions == null || definitions.Length == 0)
        throw InfoCardTrace.ThrowHelperArgumentNull(nameof (definitions));
      this.m_indexes = new Hashtable(definitions.Length, (IEqualityComparer) StringComparer.Create(CultureInfo.InvariantCulture, false));
      this.m_sortComparer = (IComparer<IntPtr>) new SecondaryIndexList.SortComparer();
      this.m_searchComparer = (IComparer<IntPtr>) new SecondaryIndexList.SearchComparer();
      for (int index = 0; index < definitions.Length; ++index)
        this.m_indexes.Add((object) definitions[index].Name, (object) new SecondaryIndex(definitions[index], this.m_searchComparer, this.m_sortComparer));
      this.m_isOpen = true;
    }

    public int Count
    {
      get
      {
        this.ThrowIfNotOpen();
        return this.m_indexes.Count;
      }
    }

    internal Hashtable InnerIndexes
    {
      get
      {
        this.ThrowIfNotOpen();
        return this.m_indexes;
      }
    }

    public void SetBuffer(string indexId, byte[] buffer, int lastIndex)
    {
      this.ThrowIfNotOpen();
      if (!this.m_indexes.ContainsKey((object) indexId))
        throw InfoCardTrace.ThrowHelperError((Exception) new ArgumentOutOfRangeException(nameof (indexId), (object) indexId, SR.GetString("StoreIndexNameInvalid")));
      if (buffer == null || buffer.Length == 0)
        throw InfoCardTrace.ThrowHelperArgumentNull(nameof (buffer));
      if ((uint) lastIndex > (uint) buffer.Length && lastIndex != -1)
        throw InfoCardTrace.ThrowHelperError((Exception) new ArgumentOutOfRangeException(nameof (lastIndex), (object) lastIndex, SR.GetString("StoreLastIndexOutOfRange")));
      ((SecondaryIndex) this.m_indexes[(object) indexId]).SetBuffer(buffer, lastIndex);
    }

    public void SetValuesForId(int localId, DataRowIndexBuffer indexBuffer, bool remove)
    {
      this.ThrowIfNotOpen();
      if (localId < 0)
        throw InfoCardTrace.ThrowHelperError((Exception) new ArgumentOutOfRangeException(nameof (localId), (object) localId, SR.GetString("StoreLocalIdOutOfRange")));
      if (indexBuffer == null)
        throw InfoCardTrace.ThrowHelperArgumentNull(nameof (indexBuffer));
      this.PreValidateIndexBuffer(indexBuffer);
      foreach (string key in (IEnumerable) this.m_indexes.Keys)
        ((SecondaryIndex) this.m_indexes[(object) key]).SetValuesForId(localId, indexBuffer, remove);
    }

    public bool Match(QueryParameter match, LocalIdCollection localIds)
    {
      this.ThrowIfNotOpen();
      if (localIds == null)
        throw InfoCardTrace.ThrowHelperArgumentNull(nameof (localIds));
      if (match == null)
        throw InfoCardTrace.ThrowHelperArgumentNull(nameof (match));
      if (!this.m_indexes.ContainsKey((object) match.IndexName))
        throw InfoCardTrace.ThrowHelperError((Exception) new ArgumentOutOfRangeException(nameof (match), (object) match.IndexName, SR.GetString("StoreIndexNameInvalid")));
      SecondaryIndex index1 = (SecondaryIndex) this.m_indexes[(object) match.IndexName];
      if (-1 == index1.LastIndex)
        return false;
      bool flag = false;
      for (int index2 = 0; index2 < match.Count; ++index2)
      {
        IndexObject indexObject = match[index2];
        if (index1.Match(indexObject, localIds, 0, index1.LastIndex) >= 0)
          flag = true;
      }
      return flag;
    }

    public void PopulateRowIndexBuffer(DataRow row)
    {
      this.ThrowIfNotOpen();
      DataRowIndexBuffer indexBuffer = row.IndexBuffer;
      foreach (string key in (IEnumerable) this.m_indexes.Keys)
        ((SecondaryIndex) this.m_indexes[(object) key]).PopulateRowIndexBuffer(row.IndexBuffer, row.LocalId);
    }

    public void RemoveAllValuesForId(int id)
    {
      foreach (string key in (IEnumerable) this.m_indexes.Keys)
        this.RemoveAllValuesForId(key, id);
    }

    public void RemoveAllValuesForId(string indexId, int id)
    {
      this.ThrowIfNotOpen();
      if (!this.m_indexes.ContainsKey((object) indexId))
        throw InfoCardTrace.ThrowHelperError((Exception) new ArgumentOutOfRangeException(nameof (indexId), (object) indexId, SR.GetString("StoreIndexNameInvalid")));
      ((SecondaryIndex) this.m_indexes[(object) indexId]).RemoveAllValuesForId(id);
    }

    public void Close()
    {
      if (!this.m_isOpen)
        return;
      foreach (string key in (IEnumerable) this.m_indexes.Keys)
        ((SecondaryIndex) this.m_indexes[(object) key]).Close();
      this.m_isOpen = false;
    }

    private void PreValidateIndexBuffer(DataRowIndexBuffer buffer)
    {
      foreach (string key in (IEnumerable) this.m_indexes.Keys)
      {
        SecondaryIndex index = (SecondaryIndex) this.m_indexes[(object) key];
        if (SecondaryIndexSettings.Nullable != (index.Definition.Settings & SecondaryIndexSettings.Nullable) && (buffer[key] == null || buffer.GetValueCount(key) == 0))
          throw InfoCardTrace.ThrowHelperError((Exception) new InvalidOperationException(SR.GetString("StoreIndexValueCanNotBeNull", (object) index.Definition.Name)));
      }
    }

    private void ThrowIfNotOpen()
    {
      if (!this.m_isOpen)
        throw InfoCardTrace.ThrowHelperError((Exception) new ObjectDisposedException(nameof (SecondaryIndexList)));
    }

    private class SearchComparer : IComparer<IntPtr>
    {
      public unsafe int Compare(IntPtr x, IntPtr y)
      {
        if (IntPtr.Zero == x)
          throw InfoCardTrace.ThrowHelperArgumentNull(nameof (x));
        if (IntPtr.Zero == y)
          throw InfoCardTrace.ThrowHelperArgumentNull(nameof (y));
        return SecondaryIndexList.SearchComparer.Compare((SecondaryIndexItem*) (void*) x, (SecondaryIndexItem*) (void*) y);
      }

      public static unsafe int Compare(SecondaryIndexItem obj1, SecondaryIndexItem obj2)
      {
        return SecondaryIndexList.SearchComparer.Compare(&obj1, &obj2);
      }

      public static unsafe int Compare(SecondaryIndexItem* pObj1, SecondaryIndexItem* pObj2)
      {
        if (IntPtr.Zero == (IntPtr) pObj1)
          throw InfoCardTrace.ThrowHelperArgumentNull(nameof (pObj1));
        if (IntPtr.Zero == (IntPtr) pObj2)
          throw InfoCardTrace.ThrowHelperArgumentNull(nameof (pObj2));
        byte* numPtr1 = &pObj1->HashValue;
        byte* numPtr2 = &pObj2->HashValue;
        for (int index = 0; index < 60; ++index)
        {
          int num = (int) numPtr1[index] - (int) numPtr2[index];
          if (num != 0)
            return num;
        }
        return 0;
      }
    }

    private class SortComparer : IComparer<IntPtr>
    {
      public unsafe int Compare(IntPtr x, IntPtr y)
      {
        if (IntPtr.Zero == x)
          throw InfoCardTrace.ThrowHelperArgumentNull(nameof (x));
        if (IntPtr.Zero == y)
          throw InfoCardTrace.ThrowHelperArgumentNull(nameof (y));
        return SecondaryIndexList.SortComparer.Compare((SecondaryIndexItem*) (void*) x, (SecondaryIndexItem*) (void*) y);
      }

      public static unsafe int Compare(SecondaryIndexItem obj1, SecondaryIndexItem obj2)
      {
        return SecondaryIndexList.SortComparer.Compare(&obj1, &obj2);
      }

      public static unsafe int Compare(SecondaryIndexItem* pObj1, SecondaryIndexItem* pObj2)
      {
        if (IntPtr.Zero == (IntPtr) pObj1)
          throw InfoCardTrace.ThrowHelperArgumentNull(nameof (pObj1));
        if (IntPtr.Zero == (IntPtr) pObj2)
          throw InfoCardTrace.ThrowHelperArgumentNull(nameof (pObj2));
        byte* numPtr1 = &pObj1->HashValue;
        byte* numPtr2 = &pObj2->HashValue;
        for (int index = 0; index < 60; ++index)
        {
          int num = (int) numPtr1[index] - (int) numPtr2[index];
          if (num != 0)
            return num;
        }
        return pObj1->LocalId - pObj2->LocalId;
      }
    }
  }
}
